/**
 * 							SYSTEM MEMEORY HEAP MANAGEMENT
 * @brief		OS kernel memory heap.
 * @author		chy.
 * @note		this file manage the virtual memory heap of OS!
 * @comment		We'd better manage memory of OS.Should avoid
 * 				wasting memory as OS would use memory by page
 * @warning	  =>We always virtual memory here!
 */

#ifndef	_K_MM_HEAP_H_
#define	_K_MM_HEAP_H_

/**
 * 							STRUCTURES DEFINES
 */

/**
 * 						ABOUT HEAP POOL AND HEAP DESIGN
 * We have create an heap pool as the space are not continuous in OS kernel.
 * Every heap pool includes many heaps! Space are continuous in heap.So, we
 * can allocate heap by pages.Heap Pool is made up by dis-continuous heaps.
 * Therefore, there are many heaps in OS kernel, but Heap Pool only one!
 *
 * One heap figure showed:
 * 				------------------------
 * 					   heap header
 * 				------------------------
 * 				   heap block header 1
 * 				------------------------
 * 				   belong heap block 1
 * 				------------------------
 * 				   belong heap block 1
 * 				------------------------
 * 				   heap block header 2
 * 				------------------------
 * 			 	   belong heap block 2
 * 				------------------------
 * 					................
 * 				------------------------
 * As we showed,there are many heap blocks in every heap.They are linked together.
 * And indicate which heap they are belonging to!
 *
 * Heap Block must be create when allocate memory!
 **/

/** HEAP BLOCK HEDADER **/
typedef struct k_mm_os_heap_block_header
{
	unsigned int	hb_mflag;								// indicate that this is an heap block...we check this value when free block
	unsigned int	hb_size;								//  size of current heap block in bytes, excluding block header
	void		    *hb_parent;								//	indicate the heap of current heap block belonging to
	struct k_mm_os_heap_block_header 	*hb_next;			//	pointer of next heap block
}K_HEAPBLOCK, *K_PHEAPBLOCK;

/** HEAP HEADER **/
typedef struct k_mm_os_heap
{
	unsigned int		heap_totalsize;		// size of current heap including header. this value must be bound of 4KB
	unsigned int		heap_usedsize;		// indicate how many bytes have been used in current heap, including heap block header(s) and heap header size
	unsigned int		heap_gcfreq;		// GC call frequency
	K_PHEAPBLOCK		heap_firsthb;		// point to the first heap block belonging to current heap unused!
	struct k_mm_os_heap	*heap_next;	        // point to next heap
}K_HEAP, *K_PHEAP;

/** HEAP POOL **/
typedef	struct k_mm_os_heap_pool_tag
{
	unsigned int	hpool_size;			// size of all heaps in heap pool
	unsigned int	hp_heapcount;		// count of heaps in heap pool
	K_PHEAP		    hp_firstheap;	    // point to the first heap in heap pool
}K_HEAPPOOL;

/** heap block header size **/
#define	K_HEAPBLOCK_HEADERSIZE			sizeof(K_HEAPBLOCK)
/** heap header size **/
#define	K_HEAP_HEADERSIZE			    sizeof(K_HEAP)


/** flags for heap block  **/
#define	K_HEAPBLOCK_HEADERFLAG_USING	0x12EE63E
#define	K_HEAPBLOCK_HEADERFLAG_FREE		0xE36EE21

/** make 4KB bound **/
#define	K_BOUND_4KB(__val__)		__val__=(__val__+((1 << 12) - 1))&(~((1 << 12) - 1))

/**
   *    COMMON FUNCTIONS
**/

/**
 * @BRIEF	: GC for a heap
 * @PARAM	: heap
 * @RETRUN	: inc bytes
 * @NOTE	: if GC success, K_SYS_OS_HEAP_GCFREQ of heap will clear to 0
 */
int	k_mm_heap_gc(K_PHEAP heap);


/**
 * @BRIEF	: free a heap
 * @PARAM	: heappool      heappool of process or OS
 * @RETRUN	: void
 * @NOTE	: this function will scan the heap pool to find
 *          : which heap can be freed.and free it.
 *          : just free one heap
 */
void k_mm_heap_freeheap(K_HEAPPOOL *heappool);

#endif	/* _K_MM_HEAP_H_ */
